package usercenter

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ UserNotifyMsgModel = (*customUserNotifyMsgModel)(nil)

type (
	// UserNotifyMsgModel is an interface to be customized, add more methods here,
	// and implement the added methods in customUserNotifyMsgModel.
	UserNotifyMsgModel interface {
		userNotifyMsgModel
		InsertTrans(ctx context.Context, tx sqlx.Session, data *UserNotifyMsg) (sql.Result, error)
		UpdateRead(ctx context.Context, tx sqlx.Session, id int64, state int64) error
		UpdateAllRead(ctx context.Context, tx sqlx.Session, uid int64, notReadState, state int64) error
		Find(ctx context.Context, uid int64, pageNo, pageSize int64) ([]*UserNotifyMsg, error)
	}

	customUserNotifyMsgModel struct {
		*defaultUserNotifyMsgModel
	}
)

// NewUserNotifyMsgModel returns a model for the database table.
func NewUserNotifyMsgModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UserNotifyMsgModel {
	return &customUserNotifyMsgModel{
		defaultUserNotifyMsgModel: newUserNotifyMsgModel(conn, c, opts...),
	}
}

func (m *customUserNotifyMsgModel) InsertTrans(ctx context.Context, tx sqlx.Session, data *UserNotifyMsg) (sql.Result, error) {
	query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?)", m.table, userNotifyMsgRowsExpectAutoSet)
	ret, err := tx.ExecCtx(ctx, query, data.Uid, data.MsgType, data.MsgContent, data.IsRead, data.Title)
	return ret, err
}

func (m *customUserNotifyMsgModel) UpdateRead(ctx context.Context, tx sqlx.Session, id int64, state int64) error {
	query := fmt.Sprintf("update %s set is_read = ? where id = ?", m.table)
	_, err := tx.ExecCtx(ctx, query, state, id)
	return err
}

func (m *customUserNotifyMsgModel) UpdateAllRead(ctx context.Context, tx sqlx.Session, uid int64, notReadState, state int64) error {
	query := fmt.Sprintf("update %s set is_read = ? where uid = ? and is_read = ?", m.table)
	_, err := tx.ExecCtx(ctx, query, state, uid, notReadState)
	return err
}

func (m *customUserNotifyMsgModel) Find(ctx context.Context, uid int64, pageNo, pageSize int64) ([]*UserNotifyMsg, error) {
	if pageNo < 1 {
		pageNo = 1
	}
	if pageSize <= 0 {
		pageSize = 10
	}
	resp := make([]*UserNotifyMsg, 0)
	query := fmt.Sprintf("select %s from %s where uid = ? order by id desc limit ? offset ?", userNotifyMsgRows, m.table)
	err := m.QueryRowsNoCacheCtx(ctx, &resp, query, uid, pageSize, (pageNo-1)*pageSize)
	switch err {
	case nil:
		return resp, nil
	default:
		return nil, err
	}
}
